/**
 * Copyright (c) 2023 myons Inc. All rights reserved.
 */
package cn.zmwh.common.core.exception;

import cn.hutool.core.util.StrUtil;
import cn.zmwh.common.core.api.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理
 *
 * @author dm
 * @since 2020/2/27.
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    @ExceptionHandler(value = RRException.class)
    public Result handle(RRException e) {
        // 打印堆栈信息
        String stackTrace = ThrowableUtil.getStackTrace(e);
        log.error(stackTrace);
        if (e.getStatus() != null) {
            return Result.failed(e.getStatus(), e.getMessage());
        }
        if (StrUtil.isBlank(e.getMessage())
//                ||NullPointerException.class.isInstance(e)
        ) {
            return Result.failed("system error");
        }
        return Result.failed(HttpStatus.PRECONDITION_FAILED.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public Result handleNullPointerException(NullPointerException e) {
        String stackTrace = ThrowableUtil.getStackTrace(e);
        log.error(stackTrace);
        return Result.failed("system error");
    }

    /**
     * 处理404异常
     *
     * @param e NoHandlerFoundException
     * @return
     */
//    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<Result> noHandlerFoundException(HttpServletRequest req, Exception e) {
        log.error("404异常 NoHandlerFoundException, method = {}, path = {} ", req.getMethod(), req.getServletPath(), e);
        return ResponseEntity.status(HttpStatus.NOT_FOUND.value()).body(Result.failed(HttpStatus.NOT_FOUND.value(), "未找到您请求的资源。"));
    }

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result handle(HttpRequestMethodNotSupportedException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        return Result.failed(HttpStatus.METHOD_NOT_ALLOWED.value(), "请求方式错误！");
    }

    @ExceptionHandler(value = DataAccessException.class)
    public Result handleDataAccessException(DataAccessException e) {
        // 打印堆栈信息
        String stackTrace = ThrowableUtil.getStackTrace(e);
        String msg = "数据库访问异常:" + stackTrace;
        log.error(msg);
        return Result.failed("data error");
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handleValidException(MethodArgumentNotValidException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return Result.validateFailed(message);
    }

    @ExceptionHandler(value = BindException.class)
    public Result handleValidException(BindException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return Result.validateFailed(message);
    }

    /**
     * 处理所有不可知的异常
     */
    @ExceptionHandler(Throwable.class)
    public Result handleException(Throwable e) {
        // 打印堆栈信息
        String stackTrace = ThrowableUtil.getStackTrace(e);
        log.error(stackTrace);
        return Result.failed("system error");
    }

}
